home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / shells / scsh-0.4 / scsh-0 / scsh-0.4.2 / scsh / utilities.scm < prev   
Text File  |  1995-10-28  |  6KB  |  218 lines

  1. ;;; Random useful utilities.
  2. ;;; Copyright (c) 1993 by Olin Shivers.
  3.  
  4. (define (del elt lis)
  5.   (letrec ((del (lambda (lis)
  6.           (if (pair? lis)
  7.               (let* ((head (car lis))
  8.                  (tail (cdr lis))
  9.                  (new-tail (del tail)))
  10.             (if (equal? head elt) new-tail
  11.                 (if (eq? tail new-tail) lis
  12.                 (cons head new-tail))))
  13.               '()))))
  14.     (del lis)))
  15.  
  16. (define (delete pred lis)
  17.   (filter (lambda (x) (not (pred x))) lis))
  18.  
  19. (define (index str c . maybe-start)
  20.   (let ((start (max 0 (optional-arg maybe-start 0)))
  21.     (len (string-length str)))
  22.     (do ((i start (+ 1 i)))
  23.     ((or (>= i len)
  24.          (char=? c (string-ref str i)))
  25.      (and (< i len) i)))))
  26.  
  27. (define (rindex str c . maybe-start)
  28.   (let* ((len (string-length str))
  29.      (start (min (optional-arg maybe-start len)
  30.              len)))
  31.     (do ((i (- start 1) (- i 1)))
  32.     ((or (< i 0)
  33.          (char=? c (string-ref str i)))
  34.      (and (>= i 0) i)))))
  35.  
  36. ;;; (f (f (f zero x1) x2) x3)
  37. ;;; [Richard's does (f x3 (f x2 (f x1 zero)))
  38. (define (reduce f zero l)
  39.   (letrec ((lp (lambda (val rest)
  40.          (if (pair? rest) (lp (f val (car rest)) (cdr rest))
  41.              val))))
  42.     (lp zero l)))
  43.                       
  44. (define (filter pred list)
  45.   (letrec ((filter (lambda (list)
  46.              (if (pair? list)
  47.              (let* ((head (car list))
  48.                 (tail (cdr list))
  49.                 (new-tail (filter tail)))
  50.                (if (pred head)
  51.                    (if (eq? tail new-tail) list
  52.                    (cons head new-tail))
  53.                    new-tail))
  54.              '()))))
  55.     (filter list)))
  56.  
  57. (define (first pred list)
  58.   (letrec ((lp (lambda (list)
  59.          (and (pair? list)
  60.               (let ((head (car list)))
  61.             (if (pred head) head
  62.                 (lp (cdr list))))))))
  63.     (lp list)))
  64.  
  65. (define any first)
  66.  
  67. ;;; Returns the first true value produced by PRED, not the list element
  68. ;;; that satisfied PRED.
  69.  
  70. (define (first? pred list)
  71.   (letrec ((lp (lambda (list)
  72.          (and (pair? list)
  73.               (or (pred (car list))
  74.               (lp (cdr list)))))))
  75.     (lp list)))
  76.  
  77. (define any? first?)
  78.  
  79. (define (every? pred list)
  80.   (letrec ((lp (lambda (list)
  81.          (or (not (pair? list))
  82.              (and (pred (car list))
  83.               (lp (cdr list)))))))
  84.     (lp list)))
  85.  
  86. (define (mapv f v)
  87.   (let* ((len (vector-length v))
  88.      (ans (make-vector len)))
  89.     (do ((i 0 (+ i 1)))
  90.     ((= i len) ans)
  91.       (vector-set! ans i (f (vector-ref v i))))))
  92.  
  93. (define (mapv! f v)
  94.   (let ((len (vector-length v)))
  95.     (do ((i 0 (+ i 1)))
  96.     ((= i len) v)
  97.       (vector-set! v i (f (vector-ref v i))))))
  98.  
  99. (define (vector-every? pred v)
  100.   (let lp ((i (- (vector-length v) 1)))
  101.     (or (< i 0)
  102.     (and (pred (vector-ref v i))
  103.          (lp (- i 1))))))
  104.  
  105. (define (copy-vector v)
  106.   (let* ((len (vector-length v))
  107.      (ans (make-vector len)))
  108.     (do ((i (- len 1) (- i 1)))
  109.     ((< i 0) ans)
  110.       (vector-set! ans i (vector-ref v i)))))
  111.  
  112. ;;; These two utility funs are for parsing optional last arguments,
  113. ;;; e.g. the PORT arg in
  114. ;;;    (write-string string [port])
  115. ;;;    (define (write-string str . maybe-port) ...).
  116.  
  117. (define (optional-arg maybe-arg default)
  118.   (cond ((null? maybe-arg) default)
  119.     ((null? (cdr maybe-arg))  (car maybe-arg))
  120.     (else (error "too many optional arguments" maybe-arg))))
  121.  
  122.  
  123. (define (optional-arg* maybe-arg default-thunk)
  124.   (if (null? maybe-arg) (default-thunk) (car maybe-arg)))
  125.  
  126. ;;; (PARSE-OPTIONALS arg-list . default-list)
  127. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  128. ;;; This function generalises OPTIONAL-ARG to the multi-argument
  129. ;;; case. ARG-LIST is a list of rest args passed to a procedure.
  130. ;;; DEFAULT-LIST are the default values for the procedure.
  131. ;;; We compute a list of values, with the elts of ARG-LIST overriding
  132. ;;; the defaults. It is an error if there are more args than defaults.
  133. ;;; The values are returned as multiple values, suitable for binding
  134. ;;; with RECEIVE.
  135. ;;;
  136. ;;; Example:
  137. ;;; (define (read-string! str . maybe-args)
  138. ;;;   (receive (port start end)
  139. ;;;            (parse-optionals maybe-args
  140. ;;;                             (current-input-port) 0 (string-length str))
  141. ;;;     ...))
  142.  
  143. (define (parse-optionals arg-list . default-list)
  144.   (let lp ((arglist arg-list)
  145.        (defaults default-list)
  146.        (vals '()))
  147.     (if (pair? defaults)
  148.     (if (pair? arglist)
  149.  
  150.         ;; The supplied arg overrides the default.
  151.         (lp (cdr arglist)
  152.         (cdr defaults)
  153.         (cons (car arglist) vals))
  154.  
  155.         ;; No more args. Use up all the remaining defaults & return.
  156.         (apply values (reverse (append (reverse defaults) vals))))
  157.  
  158.     ;; No more defaults. Better not be any more args.
  159.     (if (null? arglist)
  160.         (apply values (reverse vals))
  161.         (error "Too many optional arguments" arg-list)))))
  162.  
  163. (define (check-arg pred val caller)
  164.   (if (pred val) val
  165.       (check-arg pred (error "Bad argument" val pred caller) caller)))
  166.  
  167. (define (conjoin f g)
  168.   (lambda args (and (apply f args) (apply g args))))
  169.  
  170. (define (disjoin f g)
  171.   (lambda args (or (apply f args) (apply g args))))
  172.  
  173. (define (negate f) (lambda args (not (apply f args))))
  174.  
  175. (define (compose f g)
  176.   (lambda args (call-with-values (lambda () (apply g args)) f)))
  177.  
  178.  
  179. (define (reverse! lis)
  180.   (let lp ((lis lis) (prev '()))
  181.     (if (not (pair? lis)) prev
  182.     (let ((tail (cdr lis)))
  183.       (set-cdr! lis prev)
  184.       (lp tail lis)))))
  185.  
  186. (define call/cc call-with-current-continuation)
  187.  
  188. (define (deposit-bit-field bits mask field)
  189.   (bitwise-ior (bitwise-and field mask)
  190.            (bitwise-and bits  (bitwise-not mask))))
  191.  
  192.  
  193. (define (nth lis i)
  194.   (if (< i 0) (error "nth: illegal list index" i)
  195.       (let lp ((l lis) (i i))
  196.     (if (pair? l)
  197.         (if (zero? i) (car l)
  198.         (lp (cdr l) (- i 1)))
  199.         (error "nth: index too large" lis i)))))
  200.  
  201.  
  202. (define (deprecated-proc proc name . maybe-preferred-msg)
  203.   (let ((warned? #f))
  204.     (lambda args
  205.       (cond ((not warned?)
  206.          (set! warned? #t)
  207.          (apply warn
  208.             "Deprecated procedure (may not be supported in a future release)"
  209.             name
  210.             maybe-preferred-msg)))
  211.       (apply proc args))))
  212.  
  213.  
  214. (define (real->exact-integer x)
  215.   (let ((f (round x)))
  216.     (if (inexact? f) (inexact->exact f) f)))
  217.  
  218.